#include <cstdlib>
#include <iostream>
using namespace std;

class OrderedList {
  struct Node {
    int elem;
    Node *next;
    Node(const int &element = 0, Node *nextNode = nullptr)
      : elem(element), next(nextNode) {}
  };

public:
  OrderedList();
  /* big-five：拷贝构造、移动构造、拷贝赋值、移动赋值、析构
  */
  OrderedList(const OrderedList &lst);
  OrderedList(OrderedList &&lst);
  OrderedList& operator=(const OrderedList &lst);
  OrderedList& operator=(OrderedList &&lst);
  virtual ~OrderedList();

  ostream& output(ostream& ost) const;
  int indexOf(const int& e) const;
  void insert(const int& e);
  void merge(OrderedList& lst); // FIXME: return ref?

protected:
  Node *head;
};

OrderedList::OrderedList()
  : head() {}

OrderedList::OrderedList(const OrderedList &lst)
  : head() {
  Node *sourceNode = lst.head;
  head = new Node(sourceNode->elem);
  sourceNode = sourceNode->next;
  Node *targetNode = head;
  while(sourceNode != NULL) {
    targetNode->next = new Node(sourceNode->elem);
    targetNode = targetNode->next;
    sourceNode = sourceNode->next;
  }
  targetNode->next = NULL;
}

OrderedList::~OrderedList() {
  for(Node *pn = nullptr; head; head = pn) {
    pn = head->next;
    delete head;
  }
}

int OrderedList::indexOf(const int &e) const {
  int index = 0;
  for(Node *pn = head; pn; pn = pn->next) {
    if(pn->elem == e){
      return index;
    }
    ++index;
  }
  return -1; // not found
}

void OrderedList::insert(const int &e) {
  Node* pp = nullptr;
  for(Node *pn = head; pn && pn->elem < e; pn = pn->next) {
    pp = pn;
  }
  // pn == 0 或 pn->elem >= e
  if(pp){
    Node* pt = new Node(e, pp->next);
    pp->next = pt;
  }else{
    head = new Node(e, head);
  }
}

void OrderedList::merge(OrderedList &lst) {
  /* 定义：合并之后，lst为空，*this包含所有节点。
  */
  Node dummy;
  Node* pa = head;
  Node* pb = lst.head;
  Node* pm = &dummy;
  while(pa && pb) {
    Node* &pt = (pa->elem < pb->elem ? pa : pb);
    pm->next = pt;
    pm = pt;
    pt = pt->next;
  }
  if(pa) {
    pm->next = pa;
  }else{
    pm->next = pb;
  }
  lst.head = nullptr;
  head = dummy.next;
}

ostream& OrderedList::output(ostream &ost) const {
  for(Node *pn = head; pn; pn = pn->next) {
    if(pn != head){
      ost << ',';
    }
    ost << pn->elem;
  }
  return ost;
}

inline ostream& operator<<(ostream &ost, const OrderedList &lst) {
  return lst.output(ost);
}

OrderedList input(){ // TODO: move
  OrderedList lst;
  for(int e; cin >> e && e;) {
    lst.insert(e);
  }
  return lst;
}

int main() {
  OrderedList la = input();
  cout << "list a: " << la << endl;

  for(int x; cin >> x && x;){
    cout << "indexOf ";
    cin >> x;
    cout << x << " is " << la.indexOf(x) << endl;
  }

  OrderedList lb = input();
  cout << "list b: " << lb << endl;

  la.merge(lb);
  cout << "merged: " << la << endl;
  return 0;
}